package cn.agiledata.bank.common.servlet;

import java.io.IOException;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.orm.hibernate3.SessionFactoryUtils;
import org.springframework.orm.hibernate3.SessionHolder;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.web.filter.OncePerRequestFilter;

import cn.agiledata.bank.account.util.TransactionInterceptor;
import com.vnv.infrastructure.logic.IPBHibernate3BaseMgr;
import com.vnv.infrastructure.logic.IPBMgrFactory;

public class HibernateFilter extends OncePerRequestFilter {

	protected void doFilterInternal(HttpServletRequest request,
			HttpServletResponse response, FilterChain filterChain)
			throws ServletException, IOException {

		SessionFactory sessionFactory = lookupSessionFactory();
		Session session = SessionFactoryUtils.getNewSession(sessionFactory,
				new TransactionInterceptor());
		TransactionSynchronizationManager.bindResource(sessionFactory,
				new SessionHolder(session));

		try {
			filterChain.doFilter(request, response);
		}

		finally {
            boolean participate = false;
			if (!participate) {
				SessionHolder holder = (SessionHolder) TransactionSynchronizationManager
						.getResource(sessionFactory);
				Session s = holder.getSession();
				try {
					// if (s.getFlushMode() != FlushMode.NEVER)
					s.flush();
				} catch (RuntimeException ex) {
					logger.error("Unexpected exception on closing Hibernate Session",ex);
				} finally {
					TransactionSynchronizationManager
							.unbindResource(sessionFactory);
					if (!SessionFactoryUtils.isSessionTransactional(s, sessionFactory)){
						SessionFactoryUtils.releaseSession(s,
							null);
					}
				}
			}
		}
	}

	protected SessionFactory lookupSessionFactory() {
		SessionFactory sf = null;

		IPBHibernate3BaseMgr ipb = (IPBHibernate3BaseMgr) IPBMgrFactory
				.getMgr("ipb");
		sf = ipb.getHibernateTemplate().getSessionFactory();

		return sf;
	}
}
